package com.shangxia.monomer.study.designPatterns.behavioralType.observer;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.ApplicationEventPublisherAware;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.EventListener;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * @author zhouya38158
 * @Package com.shangxia.monomer.study.designPatterns.behavioralType.observer
 * @date 2021/8/6 14:52
 */

@EnableAsync // 开启异步
@SpringBootApplication
public class EventDemo {

    public static void main(String[] args) {
        SpringApplication.run(EventDemo.class, args);
    }

}

class UserRegisterEvent extends ApplicationEvent {

    private String username;

    public UserRegisterEvent(Object source) {
        super(source);
    }

    public UserRegisterEvent(Object source, String username) {
        super(source);
        this.username = username;
    }

    public String getUsername() {
        return username;
    }
}

/**
 * 注解方式 @EventListener
 *
 * @author Summerday
 */
@Service
@Slf4j
class CouponService {
    /**
     * 监听用户注册事件,执行发放优惠券逻辑
     */
    @EventListener
    public void addCoupon(UserRegisterEvent event) {
        log.info("给用户[{}]发放优惠券", event.getUsername());
    }
}

/**
 * 实现ApplicationListener<Event>的方式
 *
 * @author Summerday
 */
@Service
@Slf4j
class EmailService implements ApplicationListener<UserRegisterEvent> {
    /**
     * 监听用户注册事件, 异步发送执行发送邮件逻辑
     */
    @Override
    @Async
    public void onApplicationEvent(UserRegisterEvent event) {
        log.info("给用户[{}]发送邮件", event.getUsername());
    }
}

@Service
@Slf4j
 class UserService implements ApplicationEventPublisherAware {

    // 注入事件发布者
    private ApplicationEventPublisher applicationEventPublisher;

    @Override
    public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
        this.applicationEventPublisher = applicationEventPublisher;
    }

    /**
     * 发布事件
     */
    public void register(String username) {
        log.info("执行用户[{}]的注册逻辑", username);
        applicationEventPublisher.publishEvent(new UserRegisterEvent(this, username));
    }
}

@RestController
@RequestMapping("/event")
class UserEventController {

    @Autowired
    private UserService userService;

    @GetMapping("/register")
    public String register(String username){
        userService.register(username);
        return "恭喜注册成功!";
    }
}


